package com.des1gn.serviceb.aspect;

import com.des1gn.serviceb.dao.AMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName TransAspect
 * @Description TODO
 * @Author Des1gn
 * @Date 2021/12/15 11:37
 * @Version 1.0
 **/
@Component
@Aspect
@Slf4j
@RequiredArgsConstructor
public class TransAspect {

    private final AMapper aMapper;

    @Pointcut("execution(public * com.des1gn.serviceb.service.impl.*.*(..)) && @annotation(com.des1gn.serviceb.aspect.EnableTrans)")
    public void confimFunction(){}

    @AfterReturning(value = "confimFunction()",returning = "obj")
    public Object doTrans(JoinPoint point,Object obj) throws NoSuchFieldException, IllegalAccessException {
        Map<String,String> cache = new HashMap<>(10);
        if (obj instanceof List && obj != null){
          List objs = (List)obj;
          for (Object o : objs){
              trans(o,cache);
          }
        }else {
            if (obj == null){
                return obj;
            }
            trans(obj,cache);
        }
        return obj;
    }

    private void trans(Object obj,Map<String,String> cache) throws NoSuchFieldException, IllegalAccessException {
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields){
            field.setAccessible(true);
            Trans trans = field.getAnnotation(Trans.class);
            if (trans != null){
                String table = trans.table();
                String column = trans.column();
                String property = trans.property();
                Field propertyField = clazz.getDeclaredField(property);
                propertyField.setAccessible(true);
                Object propertyValue = propertyField.get(obj);
                String id = String.valueOf(propertyValue);
                String value = null;
                String hashKey = table+column+id;
                if (cache.containsKey(hashKey)){
                    value = cache.get(hashKey);
                }else {
                    value = aMapper.getTransName(table,column,id);
                    cache.put(hashKey,value);
                }
                field.set(obj,value);
            }
        }
    }


}
